package com.company.management.service.reward.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import com.company.management.constant.Constants;
import com.company.management.domain.reward.*;
import com.company.management.domain.reward.bo.RewardsBO;
import com.company.management.domain.reward.dto.RewardsAddDTO;
import com.company.management.domain.reward.dto.RewardsQueryDTO;
import com.company.management.domain.reward.vo.RewardsQueryVO;
import com.company.management.domain.reward.vo.TalentUserVO;
import com.company.management.enums.ScoreLevelFlagType;
import com.company.management.enums.ScoreModuleType;
import com.company.management.mapper.reward.RewardsMapper;
import com.company.management.mapper.reward.UserRewardsMapper;
import com.company.management.service.reward.RewardsService;
import com.company.management.service.reward.ScoreLevelService;
import com.company.management.service.reward.ScoreLogService;
import com.company.management.service.reward.TalentUserService;
import com.company.management.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.NumberUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 奖励服务接口
 * @author: wangbin
 * @time: 2025/3/1
 **/
@Service
public class RewardsServiceImpl implements RewardsService {
    @Resource
    private RewardsMapper rewardsMapper;
    @Resource
    private UserRewardsMapper userRewardsMapper;
    @Resource
    private ModelMapper modelMapper;
    @Resource
    private ScoreLogService scoreLogService;
    @Resource
    private TalentUserService talentUserService;
    @Resource
    private ScoreLevelService scoreLevelService;

    /**
     * 新增
     *
     * @param rewardsAddDTO 奖励新增dto
     */
    @Override
    @Transactional
    public void add(RewardsAddDTO rewardsAddDTO) {
        Rewards rewards = modelMapper.map(rewardsAddDTO, Rewards.class);
        if(StringUtils.isNotBlank(rewardsAddDTO.getNote())){
            rewards.setNote(rewardsAddDTO.getNote().getBytes());
        }
        //1.自定义事项保存扣分加分机制
        if(rewardsAddDTO.checkMatter()){
            ScoreLevel scoreLevel = new ScoreLevel();
            scoreLevel.buildScoreLevel(rewardsAddDTO.getMatter(),rewards.getRewardScore(),rewards.getCreateUserId());
            scoreLevel.setFlag(ScoreLevelFlagType.REEARD.getCode());
            scoreLevelService.save(scoreLevel);
            rewards.setSid(scoreLevel.getSid());
        }
        //2.校验是否是管理员
        //3.校验用户是否存在
        rewards.setRewardId(IdWorker.getId());
        rewards.setCreateDateTime(new Date());
        rewardsMapper.insert(rewards);
        //4.新增关系表数据
        List<UserRewardsKey> userRewardsKeys = buildUserRewardsKeyList(rewardsAddDTO.getUserIds(), rewards.getRewardId());
        userRewardsMapper.batchInsert(userRewardsKeys);
        //5.查询用户信息
        List<TalentUser> talentUsers = talentUserService.listByIds(rewardsAddDTO.getUserIds());
        List<ScoreLog> scoreLogs = buildScoreLog(talentUsers, rewards);
        //6.新增奖励记录表数据
        scoreLogService.insertBatch(scoreLogs);
        //7.更新用户表分数
        talentUserService.saveOrUpdateBatch(talentUsers);
    }


    private List<ScoreLog> buildScoreLog(List<TalentUser> talentUsers,Rewards rewards){
        if (CollectionUtils.isEmpty(talentUsers)){
            return Collections.emptyList();
        }
        List<ScoreLog> scoreLogs = new ArrayList<>(talentUsers.size());
        Date date = new Date();
        for (TalentUser talentUser : talentUsers) {
            ScoreLog scoreLog = new ScoreLog();
            scoreLog.setCreateDateTime(date);
            scoreLog.setUserId(talentUser.getUserId());
            scoreLog.setFid(rewards.getRewardId());
            scoreLog.setFName(Constants.REWARD_MODULE);
            Integer score = talentUser.getScore().intValue();
            scoreLog.setBeforeScore(score);
            scoreLog.setSid(rewards.getSid());
            Integer rewardScore = rewards.getRewardScore();
            scoreLog.setUpdateScore(String.format(Constants.ADD,rewardScore));
            Integer afterScore = score + rewardScore;
            scoreLog.setAfterScore(afterScore);
            scoreLogs.add(scoreLog);
            talentUser.setScore(new BigDecimal(afterScore));
        }
        return scoreLogs;
    }
    private List<UserRewardsKey> buildUserRewardsKeyList(List<Integer> userIds, Long rewardId) {
        return userIds.stream().map(userId -> {
            UserRewardsKey userRewardsKey = new UserRewardsKey();
            userRewardsKey.setUserId(userId);
            userRewardsKey.setRewardId(rewardId);
            return userRewardsKey;
        }).collect(Collectors.toList());
    }

    /**
     * 根据奖励id查询奖励信息
     *
     * @param rewardId 奖励id
     */
    @Override
    public RewardsQueryVO findByRewardId(Integer rewardId) {
        Rewards rewards = rewardsMapper.findByRewardId(rewardId);
        if (Objects.isNull(rewards)) return null;
        return getRewardsQueryVO(rewards);
    }

    private RewardsQueryVO getRewardsQueryVO(Rewards rewards) {
        RewardsQueryVO rewardsQueryVO = modelMapper.map(rewards, RewardsQueryVO.class);
        rewardsQueryVO.setRewardsDate(DateUtils.dateTime(rewards.getRewardDate()));
        if(Objects.nonNull(rewards.getNote())){
            rewardsQueryVO.setNote(new String(rewards.getNote()));
        }
        return rewardsQueryVO;
    }

    /**
     * 根据奖励id查询奖励信息
     *
     * @param rewardsQueryDTO 用户信息
     */
    @Override
    public List<RewardsQueryVO> findByUserId(RewardsQueryDTO rewardsQueryDTO) {
        TalentUser talentUser = talentUserService.findIsAdminByUserId(rewardsQueryDTO.getUserId());
        if(Objects.isNull(talentUser)){
            return Collections.emptyList();
        }
        if(!talentUser.checkIsAdmin() && CollectionUtils.isEmpty(rewardsQueryDTO.getUserIds())){
            rewardsQueryDTO.setUserIds(Arrays.asList(rewardsQueryDTO.getUserId()));
        }
        List<RewardsBO> rewards = rewardsMapper.findByUserId(DateUtils.toDate(rewardsQueryDTO.getStartTime()), DateUtils.toDate(rewardsQueryDTO.getEndTime()),rewardsQueryDTO.getUserIds());
        if (CollectionUtils.isEmpty(rewards)) {
            return Collections.emptyList();
        }
        Set<Integer> createUserIds = rewards.stream().map(p -> p.getCreateUserId()).collect(Collectors.toSet());
        List<TalentUserVO> talentUserVO = talentUserService.findByCreateUseId(createUserIds);
        Map<Integer, String> userMap = talentUserVO.stream().collect(Collectors.toMap(TalentUserVO::getUserId, TalentUserVO::getUserName, (v1, v2) -> v1));
        return rewards.stream().map(r -> {
            RewardsQueryVO rewardsQueryVO = modelMapper.map(r, RewardsQueryVO.class);
            rewardsQueryVO.setRewardsDate(DateUtils.dateTime(r.getRewardDate()));
            if(userMap.containsKey(r.getCreateUserId())){
                rewardsQueryVO.setCreateUserName(userMap.get(r.getCreateUserId()));
            }
            if(Objects.nonNull(r.getNote())){
                rewardsQueryVO.setNote(new String(r.getNote()));
            }
            return rewardsQueryVO;
        }).collect(Collectors.toList());
    }
}
